<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>视频片段移除工具</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/ffmpeg/0.11.6/ffmpeg.min.js"></script>
    <style>
      * {
        box-sizing: border-box;
        margin: 0;
        padding: 0;
        font-family: 'SF Pro Display', 'PingFang SC', 'Helvetica Neue', Arial,
          sans-serif;
      }

      :root {
        --primary-bg: #e6e7ee;
        --secondary-bg: #ffffff;
        --shadow-light: #ffffff;
        --shadow-dark: #d1d9e6;
        --accent-color: #667eea;
        --accent-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        --success-color: #4ecdc4;
        --danger-color: #ff6b6b;
        --warning-color: #feca57;
        --text-primary: #2d3748;
        --text-secondary: #718096;
        --glass-bg: rgba(255, 255, 255, 0.25);
        --glass-border: rgba(255, 255, 255, 0.18);
      }

      body {
        background: var(--primary-bg);
        color: var(--text-primary);
        height: 100vh;
        overflow: hidden;
        font-size: 14px;
        transition: all 0.3s ease;
        animation: pageLoad 0.8s ease;
      }

      @keyframes pageLoad {
        from {
          opacity: 0;
          transform: translateY(20px);
        }
        to {
          opacity: 1;
          transform: translateY(0);
        }
      }

      .app-container {
        display: flex;
        height: calc(100vh - 40px);
        max-height: 100vh;
        gap: 20px;
        padding: 20px;
        background: var(--primary-bg);
      }

      .left-panel {
        flex: 2;
        background: var(--primary-bg);
        border-radius: 25px;
        box-shadow: 20px 20px 60px var(--shadow-dark),
          -20px -20px 60px var(--shadow-light);
        display: flex;
        flex-direction: column;
        overflow: hidden;
        transition: all 0.3s ease;
      }

      .left-panel:hover {
        box-shadow: 25px 25px 70px var(--shadow-dark),
          -25px -25px 70px var(--shadow-light);
      }

      .right-panel {
        flex: 1;
        display: flex;
        flex-direction: column;
        gap: 20px;
      }

      .upload-section {
        height: 300px;
        background: var(--primary-bg);
        border-radius: 25px;
        box-shadow: 12px 12px 24px var(--shadow-dark),
          -12px -12px 24px var(--shadow-light);
        display: flex;
        flex-direction: column;
        transition: all 0.3s ease;
        position: relative;
        overflow: hidden;
      }

      .upload-section::before {
        content: '';
        position: absolute;
        top: 0;
        left: -100%;
        width: 100%;
        height: 100%;
        background: linear-gradient(
          90deg,
          transparent,
          rgba(255, 255, 255, 0.1),
          transparent
        );
        transition: left 0.8s;
      }

      .upload-section:hover::before {
        left: 100%;
      }

      .upload-section:hover {
        transform: translateY(-2px);
        box-shadow: 16px 16px 32px var(--shadow-dark),
          -16px -16px 32px var(--shadow-light);
      }

      .segments-section {
        flex: 1;
        background: var(--primary-bg);
        border-radius: 25px;
        box-shadow: 12px 12px 24px var(--shadow-dark),
          -12px -12px 24px var(--shadow-light);
        display: flex;
        flex-direction: column;
        transition: all 0.3s ease;
        position: relative;
        overflow: hidden;
      }

      .segments-section::before {
        content: '';
        position: absolute;
        top: 0;
        left: -100%;
        width: 100%;
        height: 100%;
        background: linear-gradient(
          90deg,
          transparent,
          rgba(255, 255, 255, 0.1),
          transparent
        );
        transition: left 0.8s;
      }

      .segments-section:hover::before {
        left: 100%;
      }

      .segments-section:hover {
        transform: translateY(-2px);
        box-shadow: 16px 16px 32px var(--shadow-dark),
          -16px -16px 32px var(--shadow-light);
      }

      /* 播放器区域 */
      .player-header {
        background: var(--primary-bg);
        padding: 20px 25px;
        border-bottom: none;
        display: flex;
        align-items: center;
        justify-content: space-between;
        box-shadow: inset 0 -2px 4px rgba(209, 217, 230, 0.3);
      }

      .player-title {
        font-size: 18px;
        font-weight: 600;
        color: var(--accent-color);
        background: var(--accent-gradient);
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
        background-clip: text;
      }

      .player-content {
        flex: 1;
        display: flex;
        align-items: center;
        justify-content: center;
        background: #000;
        position: relative;
        max-height: 60vh;
        min-height: 300px;
      }

      .main-video {
        width: 100%;
        height: 100%;
        object-fit: contain;
      }

      .no-video-placeholder {
        text-align: center;
        color: #666;
        font-size: 18px;
      }

      .player-controls {
        background: var(--primary-bg);
        padding: 20px 25px;
        border-top: none;
        box-shadow: inset 0 2px 4px rgba(209, 217, 230, 0.3);
      }

      .control-bar {
        display: flex;
        align-items: center;
        gap: 15px;
        margin-bottom: 10px;
      }

      .play-btn {
        background: var(--accent-gradient);
        color: white;
        border: none;
        padding: 12px 20px;
        border-radius: 15px;
        cursor: pointer;
        font-size: 14px;
        min-width: 80px;
        font-weight: 600;
        box-shadow: 8px 8px 16px var(--shadow-dark),
          -8px -8px 16px var(--shadow-light),
          inset 0 1px 0 rgba(255, 255, 255, 0.2);
        transition: all 0.3s ease;
        position: relative;
        overflow: hidden;
      }

      .play-btn::before {
        content: '';
        position: absolute;
        top: 0;
        left: -100%;
        width: 100%;
        height: 100%;
        background: linear-gradient(
          90deg,
          transparent,
          rgba(255, 255, 255, 0.2),
          transparent
        );
        transition: left 0.5s;
      }

      .play-btn:hover::before {
        left: 100%;
      }

      .play-btn:hover {
        transform: translateY(-3px);
        box-shadow: 12px 12px 24px var(--shadow-dark),
          -12px -12px 24px var(--shadow-light),
          inset 0 1px 0 rgba(255, 255, 255, 0.2),
          0 0 30px rgba(102, 126, 234, 0.3);
      }

      .play-btn:active {
        transform: translateY(0);
        box-shadow: inset 6px 6px 12px var(--shadow-dark),
          inset -6px -6px 12px var(--shadow-light);
      }

      .time-display {
        font-family: 'Courier New', monospace;
        color: var(--text-secondary);
        min-width: 120px;
        font-size: 13px;
      }

      .progress-container {
        flex: 1;
        height: 16px;
        background: var(--primary-bg);
        border-radius: 20px;
        cursor: pointer;
        position: relative;
        box-shadow: inset 6px 6px 12px var(--shadow-dark),
          inset -6px -6px 12px var(--shadow-light);
        overflow: visible;
      }

      .progress-fill {
        height: 100%;
        background: var(--accent-gradient);
        border-radius: 20px;
        width: 0%;
        transition: width 0.1s ease;
        box-shadow: 0 2px 10px rgba(102, 126, 234, 0.3);
        position: relative;
        overflow: hidden;
      }

      .progress-fill::after {
        content: '';
        position: absolute;
        top: 0;
        left: -100%;
        width: 100%;
        height: 100%;
        background: linear-gradient(
          90deg,
          transparent,
          rgba(255, 255, 255, 0.3),
          transparent
        );
        animation: progressShine 2s infinite;
      }

      @keyframes progressShine {
        0% {
          left: -100%;
        }
        100% {
          left: 100%;
        }
      }

      .segment-markers {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        pointer-events: none;
      }

      .segment-marker {
        position: absolute;
        top: -2px;
        width: 2px;
        height: 20px;
        border-radius: 1px;
        background: var(--danger-color);
        box-shadow: 0 0 4px rgba(255, 107, 107, 0.5);
      }

      .remove-segment {
        position: absolute;
        top: 0;
        height: 100%;
        background: rgba(255, 107, 107, 0.3);
        border: 2px solid var(--danger-color);
        border-radius: 4px;
        pointer-events: none;
        z-index: 2;
      }

      .remove-segment::before {
        content: '';
        position: absolute;
        left: -2px;
        top: -2px;
        width: 4px;
        height: calc(100% + 4px);
        background: var(--danger-color);
        border-radius: 2px;
      }

      .remove-segment::after {
        content: '';
        position: absolute;
        right: -2px;
        top: -2px;
        width: 4px;
        height: calc(100% + 4px);
        background: var(--danger-color);
        border-radius: 2px;
      }

      .range-selection {
        position: absolute;
        top: 0;
        height: 100%;
        background: rgba(102, 126, 234, 0.3);
        border: 2px solid var(--accent-color);
        border-radius: 4px;
        pointer-events: none;
        z-index: 2;
        display: none;
      }

      .range-selection::before {
        content: '';
        position: absolute;
        left: -2px;
        top: -2px;
        width: 4px;
        height: calc(100% + 4px);
        background: var(--success-color);
        border-radius: 2px;
      }

      .range-selection::after {
        content: '';
        position: absolute;
        right: -2px;
        top: -2px;
        width: 4px;
        height: calc(100% + 4px);
        background: var(--danger-color);
        border-radius: 2px;
      }

      /* 进度条悬停提示 */
      .progress-tooltip {
        position: absolute;
        bottom: 100%;
        left: 0;
        background: rgba(0, 0, 0, 0.9);
        color: white;
        padding: 8px 12px;
        border-radius: 6px;
        font-size: 12px;
        white-space: nowrap;
        pointer-events: none;
        opacity: 0;
        visibility: hidden;
        transition: opacity 0.2s ease, visibility 0.2s ease;
        z-index: 1000;
        margin-bottom: 8px;
      }

      .progress-tooltip::after {
        content: '';
        position: absolute;
        top: 100%;
        left: 50%;
        transform: translateX(-50%);
        border: 4px solid transparent;
        border-top-color: rgba(0, 0, 0, 0.9);
      }

      .progress-tooltip.show {
        opacity: 1;
        visibility: visible;
      }

      .progress-preview {
        width: 240px;
        height: 160px;
        background: #000;
        border-radius: 4px;
        margin-bottom: 6px;
        overflow: hidden;
        position: relative;
      }

      .progress-preview video {
        width: 100%;
        height: 100%;
        object-fit: cover;
      }

      .progress-preview-placeholder {
        width: 100%;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
        color: #666;
        font-size: 24px;
      }

      .mark-buttons {
        display: flex;
        gap: 10px;
      }

      .mark-btn {
        background: var(--primary-bg);
        color: var(--text-primary);
        border: none;
        padding: 10px 16px;
        border-radius: 15px;
        cursor: pointer;
        font-size: 12px;
        font-weight: 600;
        box-shadow: 8px 8px 16px var(--shadow-dark),
          -8px -8px 16px var(--shadow-light);
        transition: all 0.3s ease;
        position: relative;
        overflow: hidden;
      }

      .mark-btn::before {
        content: '';
        position: absolute;
        top: 0;
        left: -100%;
        width: 100%;
        height: 100%;
        background: linear-gradient(
          90deg,
          transparent,
          rgba(255, 255, 255, 0.2),
          transparent
        );
        transition: left 0.5s;
      }

      .mark-btn:hover::before {
        left: 100%;
      }

      .mark-btn:hover {
        transform: translateY(-3px);
        box-shadow: 12px 12px 24px var(--shadow-dark),
          -12px -12px 24px var(--shadow-light);
      }

      .mark-btn:active {
        transform: translateY(0);
        box-shadow: inset 6px 6px 12px var(--shadow-dark),
          inset -6px -6px 12px var(--shadow-light);
      }

      .mark-btn.remove {
        color: var(--danger-color);
      }

      /* 上传区域 */
      .section-header {
        background: var(--primary-bg);
        padding: 20px 25px;
        border-bottom: none;
        display: flex;
        align-items: center;
        justify-content: space-between;
        box-shadow: inset 0 -2px 4px rgba(209, 217, 230, 0.3);
      }

      .section-title {
        font-size: 16px;
        font-weight: 600;
        color: var(--accent-color);
        background: var(--accent-gradient);
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
        background-clip: text;
      }

      .upload-area {
        flex: 1;
        display: flex;
        align-items: center;
        justify-content: center;
        border: 2px dashed var(--accent-color);
        border-radius: 15px;
        margin: 20px;
        cursor: pointer;
        transition: all 0.3s ease;
        position: relative;
        overflow: hidden;
      }

      .upload-area:hover {
        border-color: #7c8ef7;
        background: rgba(102, 126, 234, 0.05);
      }

      .upload-area.dragover {
        border-color: var(--success-color);
        background: rgba(78, 205, 196, 0.1);
      }

      .upload-content {
        text-align: center;
        padding: 40px;
      }

      .upload-icon {
        font-size: 48px;
        color: var(--accent-color);
        margin-bottom: 15px;
      }

      .upload-text {
        font-size: 16px;
        color: var(--text-primary);
        margin-bottom: 8px;
      }

      .upload-hint {
        font-size: 12px;
        color: var(--text-secondary);
      }

      .file-input {
        display: none;
      }

      /* 片段列表区域 */
      .segments-list {
        flex: 1;
        overflow-y: auto;
        padding: 20px;
      }

      .segment-item {
        display: flex;
        align-items: center;
        gap: 15px;
        margin-bottom: 15px;
        padding: 20px;
        background: var(--primary-bg);
        border-radius: 20px;
        font-size: 13px;
        box-shadow: 8px 8px 16px var(--shadow-dark),
          -8px -8px 16px var(--shadow-light);
        transition: all 0.3s ease;
        position: relative;
        overflow: hidden;
      }

      .segment-item::before {
        content: '';
        position: absolute;
        top: 0;
        left: -100%;
        width: 100%;
        height: 100%;
        background: linear-gradient(
          90deg,
          transparent,
          rgba(255, 255, 255, 0.1),
          transparent
        );
        transition: left 0.8s;
      }

      .segment-item:hover::before {
        left: 100%;
      }

      .segment-item:hover {
        transform: translateY(-2px);
        box-shadow: 12px 12px 24px var(--shadow-dark),
          -12px -12px 24px var(--shadow-light);
      }

      .segment-info {
        flex: 1;
        display: flex;
        flex-direction: column;
        gap: 8px;
      }

      .segment-time {
        display: flex;
        align-items: center;
        gap: 10px;
        font-weight: 600;
        color: var(--danger-color);
      }

      .time-input {
        background: var(--primary-bg);
        border: none;
        padding: 8px 12px;
        border-radius: 10px;
        font-size: 12px;
        width: 80px;
        text-align: center;
        box-shadow: inset 4px 4px 8px var(--shadow-dark),
          inset -4px -4px 8px var(--shadow-light);
        transition: all 0.3s ease;
      }

      .time-input:focus {
        outline: none;
        box-shadow: inset 6px 6px 12px var(--shadow-dark),
          inset -6px -6px 12px var(--shadow-light),
          0 0 0 2px rgba(102, 126, 234, 0.3);
      }

      .segment-duration {
        font-size: 11px;
        color: var(--text-secondary);
      }

      .remove-segment-btn {
        background: var(--danger-color);
        color: white;
        border: none;
        padding: 10px 15px;
        border-radius: 12px;
        cursor: pointer;
        font-size: 12px;
        font-weight: 600;
        box-shadow: 6px 6px 12px var(--shadow-dark),
          -6px -6px 12px var(--shadow-light);
        transition: all 0.3s ease;
        position: relative;
        overflow: hidden;
      }

      .remove-segment-btn::before {
        content: '';
        position: absolute;
        top: 0;
        left: -100%;
        width: 100%;
        height: 100%;
        background: linear-gradient(
          90deg,
          transparent,
          rgba(255, 255, 255, 0.2),
          transparent
        );
        transition: left 0.5s;
      }

      .remove-segment-btn:hover::before {
        left: 100%;
      }

      .remove-segment-btn:hover {
        transform: translateY(-2px);
        box-shadow: 8px 8px 16px var(--shadow-dark),
          -8px -8px 16px var(--shadow-light);
      }

      .add-segment-btn {
        background: var(--accent-gradient);
        color: white;
        border: none;
        padding: 15px 25px;
        border-radius: 15px;
        cursor: pointer;
        font-size: 14px;
        font-weight: 600;
        box-shadow: 8px 8px 16px var(--shadow-dark),
          -8px -8px 16px var(--shadow-light),
          inset 0 1px 0 rgba(255, 255, 255, 0.2);
        transition: all 0.3s ease;
        position: relative;
        overflow: hidden;
        width: 100%;
        margin: 20px;
      }

      .add-segment-btn::before {
        content: '';
        position: absolute;
        top: 0;
        left: -100%;
        width: 100%;
        height: 100%;
        background: linear-gradient(
          90deg,
          transparent,
          rgba(255, 255, 255, 0.2),
          transparent
        );
        transition: left 0.5s;
      }

      .add-segment-btn:hover::before {
        left: 100%;
      }

      .add-segment-btn:hover {
        transform: translateY(-3px);
        box-shadow: 12px 12px 24px var(--shadow-dark),
          -12px -12px 24px var(--shadow-light),
          inset 0 1px 0 rgba(255, 255, 255, 0.2),
          0 0 30px rgba(102, 126, 234, 0.3);
      }

      .process-btn {
        background: var(--success-color);
        color: white;
        border: none;
        padding: 15px 30px;
        border-radius: 15px;
        cursor: pointer;
        font-size: 16px;
        font-weight: 600;
        box-shadow: 8px 8px 16px var(--shadow-dark),
          -8px -8px 16px var(--shadow-light),
          inset 0 1px 0 rgba(255, 255, 255, 0.2);
        transition: all 0.3s ease;
        position: relative;
        overflow: hidden;
        width: 100%;
        margin: 20px;
      }

      .process-btn::before {
        content: '';
        position: absolute;
        top: 0;
        left: -100%;
        width: 100%;
        height: 100%;
        background: linear-gradient(
          90deg,
          transparent,
          rgba(255, 255, 255, 0.2),
          transparent
        );
        transition: left 0.5s;
      }

      .process-btn:hover::before {
        left: 100%;
      }

      .process-btn:hover {
        transform: translateY(-3px);
        box-shadow: 12px 12px 24px var(--shadow-dark),
          -12px -12px 24px var(--shadow-light),
          inset 0 1px 0 rgba(255, 255, 255, 0.2),
          0 0 30px rgba(78, 205, 196, 0.3);
      }

      .process-btn:disabled {
        opacity: 0.6;
        cursor: not-allowed;
        transform: none;
      }

      /* 进度显示 */
      .progress-section {
        padding: 20px;
        background: var(--primary-bg);
        border-radius: 15px;
        margin: 20px;
        box-shadow: inset 6px 6px 12px var(--shadow-dark),
          inset -6px -6px 12px var(--shadow-light);
        display: none;
      }

      .progress-section.show {
        display: block;
      }

      .progress-bar {
        width: 100%;
        height: 20px;
        background: var(--primary-bg);
        border-radius: 10px;
        overflow: hidden;
        box-shadow: inset 4px 4px 8px var(--shadow-dark),
          inset -4px -4px 8px var(--shadow-light);
        margin-bottom: 10px;
      }

      .progress-bar-fill {
        height: 100%;
        background: var(--accent-gradient);
        width: 0%;
        transition: width 0.3s ease;
        border-radius: 10px;
        position: relative;
        overflow: hidden;
      }

      .progress-bar-fill::after {
        content: '';
        position: absolute;
        top: 0;
        left: -100%;
        width: 100%;
        height: 100%;
        background: linear-gradient(
          90deg,
          transparent,
          rgba(255, 255, 255, 0.3),
          transparent
        );
        animation: progressShine 1.5s infinite;
      }

      .progress-text {
        text-align: center;
        font-size: 14px;
        color: var(--text-primary);
        font-weight: 600;
      }

      /* 下载区域 */
      .download-section {
        padding: 20px;
        background: var(--primary-bg);
        border-radius: 15px;
        margin: 20px;
        box-shadow: 8px 8px 16px var(--shadow-dark),
          -8px -8px 16px var(--shadow-light);
        display: none;
        text-align: center;
      }

      .download-section.show {
        display: block;
      }

      .download-btn {
        background: var(--success-color);
        color: white;
        border: none;
        padding: 15px 30px;
        border-radius: 15px;
        cursor: pointer;
        font-size: 16px;
        font-weight: 600;
        box-shadow: 8px 8px 16px var(--shadow-dark),
          -8px -8px 16px var(--shadow-light),
          inset 0 1px 0 rgba(255, 255, 255, 0.2);
        transition: all 0.3s ease;
        position: relative;
        overflow: hidden;
      }

      .download-btn::before {
        content: '';
        position: absolute;
        top: 0;
        left: -100%;
        width: 100%;
        height: 100%;
        background: linear-gradient(
          90deg,
          transparent,
          rgba(255, 255, 255, 0.2),
          transparent
        );
        transition: left 0.5s;
      }

      .download-btn:hover::before {
        left: 100%;
      }

      .download-btn:hover {
        transform: translateY(-3px);
        box-shadow: 12px 12px 24px var(--shadow-dark),
          -12px -12px 24px var(--shadow-light),
          inset 0 1px 0 rgba(255, 255, 255, 0.2),
          0 0 30px rgba(78, 205, 196, 0.3);
      }

      /* 日志图标按钮样式 */
      .log-icon-btn {
        background: var(--primary-bg);
        color: var(--text-primary);
        border: none;
        padding: 8px 12px;
        border-radius: 10px;
        cursor: pointer;
        font-size: 16px;
        box-shadow: 6px 6px 12px var(--shadow-dark),
          -6px -6px 12px var(--shadow-light);
        transition: all 0.3s ease;
        margin-left: 10px;
      }

      .log-icon-btn:hover {
        transform: translateY(-2px);
        box-shadow: 8px 8px 16px var(--shadow-dark),
          -8px -8px 16px var(--shadow-light);
      }

      /* 日志模态框样式 */
      .log-modal {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: rgba(0, 0, 0, 0.5);
        z-index: 1000;
        display: flex;
        justify-content: center;
        align-items: center;
      }

      .log-modal-content {
        background: var(--primary-bg);
        border-radius: 20px;
        width: 80%;
        max-width: 600px;
        max-height: 80%;
        display: flex;
        flex-direction: column;
      }

      .log-modal-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 20px;
        border-bottom: 1px solid var(--border-color);
      }

      .log-modal-header h3 {
        margin: 0;
        color: var(--text-primary);
      }

      .log-modal-close {
        background: none;
        border: none;
        font-size: 24px;
        cursor: pointer;
        color: var(--text-secondary);
        padding: 5px;
        border-radius: 50%;
        width: 35px;
        height: 35px;
        display: flex;
        align-items: center;
        justify-content: center;
        transition: all 0.3s ease;
      }

      .log-modal-close:hover {
        background: var(--secondary-bg);
        color: var(--text-primary);
      }

      .log-modal-body {
        flex: 1;
        padding: 20px;
        overflow: hidden;
      }

      .log-modal-footer {
        display: flex;
        justify-content: flex-end;
        gap: 10px;
        padding: 20px;
        border-top: 1px solid var(--border-color);
      }

      .log-download-btn {
        background: var(--accent-gradient);
        color: white;
        border: none;
        padding: 10px 20px;
        border-radius: 10px;
        cursor: pointer;
        font-size: 14px;
        box-shadow: 6px 6px 12px var(--shadow-dark),
          -6px -6px 12px var(--shadow-light);
        transition: all 0.3s ease;
      }

      .log-download-btn:hover {
        transform: translateY(-2px);
        box-shadow: 8px 8px 16px var(--shadow-dark),
          -8px -8px 16px var(--shadow-light);
      }

      .log-container {
        background: var(--secondary-bg);
        border-radius: 15px;
        padding: 15px;
        height: 300px;
        overflow-y: auto;
        box-shadow: inset 6px 6px 12px var(--shadow-dark),
          inset -6px -6px 12px var(--shadow-light);
      }

      .log-content {
        font-family: 'Consolas', 'Monaco', monospace;
        font-size: 12px;
        line-height: 1.4;
        color: var(--text-primary);
      }

      .log-entry {
        margin-bottom: 5px;
        padding: 5px 8px;
        border-radius: 5px;
        border-left: 3px solid transparent;
      }

      .log-entry.info {
        border-left-color: var(--accent-color);
        background: rgba(102, 126, 234, 0.1);
      }

      .log-entry.success {
        border-left-color: var(--success-color);
        background: rgba(78, 205, 196, 0.1);
      }

      .log-entry.error {
        border-left-color: var(--danger-color);
        background: rgba(255, 107, 107, 0.1);
      }

      .log-entry.warning {
        border-left-color: var(--warning-color);
        background: rgba(254, 202, 87, 0.1);
      }

      .log-timestamp {
        color: var(--text-secondary);
        font-size: 11px;
        margin-right: 8px;
      }

      .log-clear-btn {
        background: var(--primary-bg);
        color: var(--text-primary);
        border: none;
        padding: 10px 20px;
        border-radius: 10px;
        cursor: pointer;
        font-size: 14px;
        font-weight: 500;
        box-shadow: 6px 6px 12px var(--shadow-dark),
          -6px -6px 12px var(--shadow-light);
        transition: all 0.3s ease;
      }

      .log-clear-btn:hover {
        transform: translateY(-1px);
        box-shadow: 8px 8px 16px var(--shadow-dark),
          -8px -8px 16px var(--shadow-light);
      }

      /* 响应式设计 */
      @media (max-width: 1200px) {
        .app-container {
          flex-direction: column;
          height: auto;
          min-height: calc(100vh - 40px);
        }

        .left-panel {
          flex: none;
          height: 400px;
        }

        .right-panel {
          flex: none;
        }

        .upload-section {
          height: 150px;
        }

        .segments-section {
          height: 300px;
        }
      }

      @media (max-width: 768px) {
        .app-container {
          padding: 10px;
          gap: 10px;
        }

        .control-bar {
          flex-wrap: wrap;
          gap: 10px;
        }

        .time-display {
          min-width: auto;
        }

        .segment-item {
          flex-direction: column;
          align-items: stretch;
          gap: 10px;
        }

        .segment-time {
          justify-content: center;
        }
      }
    </style>
  </head>
  <body>
    <div class="app-container">
      <!-- 左侧播放器面板 -->
      <div class="left-panel">
        <div class="player-header">
          <h2 class="player-title">视频预览</h2>
        </div>
        <div class="player-content">
          <video
            class="main-video"
            id="mainVideo"
            controls
            style="display: none"
          ></video>
          <div class="no-video-placeholder" id="noVideoPlaceholder">
            📹 请上传视频文件
          </div>
        </div>
        <div class="player-controls">
          <div class="control-bar">
            <button class="play-btn" id="playBtn">播放</button>
            <span class="time-display" id="timeDisplay">00:00 / 00:00</span>
            <div class="progress-container" id="progressContainer">
              <div class="progress-fill" id="progressFill"></div>
              <div class="segment-markers" id="segmentMarkers"></div>
              <div class="range-selection" id="rangeSelection"></div>
              <div class="progress-tooltip" id="progressTooltip">
                <div class="progress-preview" id="progressPreview">
                  <div class="progress-preview-placeholder">📹</div>
                </div>
                <div class="progress-time" id="progressTime">00:00</div>
              </div>
            </div>
            <div class="mark-buttons">
              <button class="mark-btn remove" id="markStartBtn">
                标记开始
              </button>
              <button class="mark-btn remove" id="markEndBtn">标记结束</button>
            </div>
          </div>
        </div>
      </div>

      <!-- 右侧控制面板 -->
      <div class="right-panel">
        <!-- 上传区域 -->
        <div class="upload-section">
          <div class="section-header">
            <h3 class="section-title">视频上传</h3>
          </div>
          <div class="upload-area" id="uploadArea">
            <div class="upload-content">
              <div class="upload-icon">📁</div>
              <div class="upload-text">点击或拖拽上传视频</div>
              <div class="upload-hint">支持 MP4, AVI, MOV, MKV 格式</div>
            </div>
            <input
              type="file"
              class="file-input"
              id="fileInput"
              accept="video/*"
            />
          </div>
        </div>

        <!-- 片段管理区域 -->
        <div class="segments-section">
          <div class="section-header">
            <h3 class="section-title">移除片段</h3>
            <button class="log-icon-btn" id="logIconBtn" title="查看处理日志">
              📋
            </button>
          </div>
          <div class="segments-list" id="segmentsList">
            <div
              class="segment-item"
              style="display: none"
              id="segmentTemplate"
            >
              <div class="segment-info">
                <div class="segment-time">
                  <span>开始:</span>
                  <input
                    type="text"
                    class="time-input start-time"
                    placeholder="00:00"
                  />
                  <span>结束:</span>
                  <input
                    type="text"
                    class="time-input end-time"
                    placeholder="00:00"
                  />
                </div>
                <div class="segment-duration">
                  片段时长: <span class="duration-text">0秒</span>
                </div>
              </div>
              <button class="remove-segment-btn">删除</button>
            </div>
          </div>
          <button class="add-segment-btn" id="addSegmentBtn">
            + 添加移除片段
          </button>
          <button class="process-btn" id="processBtn" disabled>
            开始处理视频
          </button>

          <!-- 进度显示 -->
          <div class="progress-section" id="progressSection">
            <div class="progress-bar">
              <div class="progress-bar-fill" id="progressBarFill"></div>
            </div>
            <div class="progress-text" id="progressText">处理中...</div>
          </div>

          <!-- 下载区域 -->
          <div class="download-section" id="downloadSection">
            <h4 style="margin-bottom: 15px; color: var(--success-color)">
              ✅ 处理完成!
            </h4>
            <button class="download-btn" id="downloadBtn">
              下载处理后的视频
            </button>
          </div>
        </div>
      </div>
      <!-- 日志模态框 -->
      <div class="log-modal" id="logModal" style="display: none">
        <div class="log-modal-content">
          <div class="log-modal-header">
            <h3>处理日志</h3>
            <button class="log-modal-close" id="logModalClose">×</button>
          </div>
          <div class="log-modal-body">
            <div class="log-container" id="logContainer">
              <div class="log-content" id="logContent">
                <!-- 日志内容将在这里显示 -->
              </div>
            </div>
          </div>
          <div class="log-modal-footer">
            <button
              class="log-download-btn"
              id="logDownloadBtn"
              title="下载日志"
            >
              📥 下载日志
            </button>
            <button class="log-clear-btn" id="logClearBtn">清空日志</button>
          </div>
        </div>
      </div>
    </div>

    <script>
      class VideoSegmentRemover {
        constructor() {
          this.video = null
          this.ffmpeg = null
          this.segments = []
          this.currentSegment = { start: null, end: null }
          this.isFFmpegLoaded = false

          // Tooltip 相关变量
          this.previewVideo = null
          this.tooltipVisible = false

          // 长按范围选择相关变量
          this.isLongPress = false
          this.isSelecting = false
          this.isProgressInteracting = false
          this.clickTimer = null
          this.longPressThreshold = 300 // 300ms
          this.selectionStartX = 0
          this.selectionStartTime = 0
          this.selectionEndTime = 0
          this.rangeSelectionElement = null

          this.initElements()
          this.bindEvents()
          this.loadFFmpeg()
        }

        initElements() {
          // 视频相关元素
          this.mainVideo = document.getElementById('mainVideo')
          this.noVideoPlaceholder =
            document.getElementById('noVideoPlaceholder')
          this.playBtn = document.getElementById('playBtn')
          this.timeDisplay = document.getElementById('timeDisplay')
          this.progressContainer = document.getElementById('progressContainer')
          this.progressFill = document.getElementById('progressFill')
          this.segmentMarkers = document.getElementById('segmentMarkers')
          this.rangeSelectionElement = document.getElementById('rangeSelection')

          // Tooltip 相关元素
          this.progressTooltip = document.getElementById('progressTooltip')
          this.progressPreview = document.getElementById('progressPreview')
          this.progressTime = document.getElementById('progressTime')

          // 日志相关元素
          this.logIconBtn = document.getElementById('logIconBtn')
          this.logModal = document.getElementById('logModal')
          this.logModalClose = document.getElementById('logModalClose')
          this.logContent = document.getElementById('logContent')
          this.logDownloadBtn = document.getElementById('logDownloadBtn')
          this.logClearBtn = document.getElementById('logClearBtn')

          // 日志系统
          this.logs = []

          // 上传相关元素
          this.uploadArea = document.getElementById('uploadArea')
          this.fileInput = document.getElementById('fileInput')

          // 片段相关元素
          this.segmentsList = document.getElementById('segmentsList')
          this.segmentTemplate = document.getElementById('segmentTemplate')
          this.addSegmentBtn = document.getElementById('addSegmentBtn')
          this.markStartBtn = document.getElementById('markStartBtn')
          this.markEndBtn = document.getElementById('markEndBtn')

          // 处理相关元素
          this.processBtn = document.getElementById('processBtn')
          this.progressSection = document.getElementById('progressSection')
          this.progressBarFill = document.getElementById('progressBarFill')
          this.progressText = document.getElementById('progressText')
          this.downloadSection = document.getElementById('downloadSection')
          this.downloadBtn = document.getElementById('downloadBtn')

          // Tooltip 相关元素
          this.progressTooltip = document.getElementById('progressTooltip')
          this.progressPreview = document.getElementById('progressPreview')
          this.progressTime = document.getElementById('progressTime')
        }

        bindEvents() {
          // 文件上传事件
          this.uploadArea.addEventListener('click', () =>
            this.fileInput.click()
          )
          this.fileInput.addEventListener('change', (e) =>
            this.handleFileSelect(e)
          )

          // 拖拽上传事件
          this.uploadArea.addEventListener('dragover', (e) => {
            e.preventDefault()
            this.uploadArea.classList.add('dragover')
          })

          this.uploadArea.addEventListener('dragleave', () => {
            this.uploadArea.classList.remove('dragover')
          })

          this.uploadArea.addEventListener('drop', (e) => {
            e.preventDefault()
            this.uploadArea.classList.remove('dragover')
            const files = e.dataTransfer.files
            if (files.length > 0) {
              this.loadVideo(files[0])
            }
          })

          // 视频播放控制事件
          this.playBtn.addEventListener('click', () => this.togglePlay())
          this.mainVideo.addEventListener('timeupdate', () => {
            this.updateProgress()
            this.updateTimeDisplay()
          })
          this.mainVideo.addEventListener('loadedmetadata', () =>
            this.onVideoLoaded()
          )

          // 进度条交互事件（点击跳转和长按选择）
          this.progressContainer.addEventListener('mousedown', (e) =>
            this.handleProgressMouseDown(e)
          )
          this.progressContainer.addEventListener('mousemove', (e) =>
            this.handleProgressMouseMove(e)
          )
          this.progressContainer.addEventListener('mouseup', (e) =>
            this.handleProgressMouseUp(e)
          )
          document.addEventListener('mouseup', (e) =>
            this.handleProgressMouseUp(e)
          ) // 全局监听，防止鼠标移出进度条

          // 进度条tooltip事件
          this.progressContainer.addEventListener('mouseenter', () =>
            this.showProgressTooltip()
          )
          this.progressContainer.addEventListener('mouseleave', () =>
            this.hideProgressTooltip()
          )

          // 标记按钮事件
          this.markStartBtn.addEventListener('click', () =>
            this.markTime('start')
          )
          this.markEndBtn.addEventListener('click', () => this.markTime('end'))

          // 片段管理事件
          this.addSegmentBtn.addEventListener('click', () => this.addSegment())

          // 处理按钮事件
          this.processBtn.addEventListener('click', () => this.processVideo())

          // 日志相关事件
          this.logIconBtn.addEventListener('click', () => this.openLogModal())
          this.logModalClose.addEventListener('click', () =>
            this.closeLogModal()
          )
          this.logDownloadBtn.addEventListener('click', () =>
            this.downloadLogs()
          )
          this.logClearBtn.addEventListener('click', () => this.clearLogs())

          // 点击模态框背景关闭
          this.logModal.addEventListener('click', (e) => {
            if (e.target === this.logModal) {
              this.closeLogModal()
            }
          })
        }

        async loadFFmpeg() {
          try {
            this.addLog('开始加载 FFmpeg...', 'info')
            this.ffmpeg = FFmpeg.createFFmpeg({
              log: true,
              logger: ({ type, message }) => {
                if (type === 'fferr' || type === 'ffout') {
                  this.addLog(
                    `FFmpeg: ${message}`,
                    type === 'fferr' ? 'error' : 'info'
                  )
                }
              },
            })
            await this.ffmpeg.load()
            this.isFFmpegLoaded = true
            this.addLog('FFmpeg 加载成功', 'success')
            console.log('FFmpeg 加载成功')
          } catch (error) {
            this.addLog(`FFmpeg 加载失败: ${error.message}`, 'error')
            console.error('FFmpeg 加载失败:', error)
            alert('FFmpeg 加载失败，请刷新页面重试')
          }
        }

        handleFileSelect(event) {
          const file = event.target.files[0]
          if (file) {
            this.addLog(`用户选择了文件: ${file.name}`, 'info')
            this.loadVideo(file)
          }
        }

        loadVideo(file) {
          if (!file.type.startsWith('video/')) {
            this.addLog(`无效的文件类型: ${file.type}`, 'error')
            alert('请选择视频文件')
            return
          }

          this.addLog(
            `开始加载视频: ${file.name} (${(file.size / 1024 / 1024).toFixed(
              2
            )} MB)`,
            'info'
          )

          const url = URL.createObjectURL(file)
          this.mainVideo.src = url
          this.mainVideo.style.display = 'block'
          this.noVideoPlaceholder.style.display = 'none'

          // 保存原始文件
          this.originalFile = file

          // 重置状态
          this.segments = []
          this.currentSegment = { start: null, end: null }
          this.updateSegmentsList()
          this.updateSegmentMarkers()
          this.processBtn.disabled = true

          this.addLog('视频文件已加载，状态已重置', 'success')
        }

        onVideoLoaded() {
          this.updateTimeDisplay()
          this.processBtn.disabled = this.segments.length === 0
        }

        togglePlay() {
          if (this.mainVideo.paused) {
            this.mainVideo.play()
            this.playBtn.textContent = '暂停'
          } else {
            this.mainVideo.pause()
            this.playBtn.textContent = '播放'
          }
        }

        updateProgress() {
          if (this.mainVideo.duration) {
            const progress =
              (this.mainVideo.currentTime / this.mainVideo.duration) * 100
            this.progressFill.style.width = progress + '%'
            this.updateTimeDisplay()
          }
        }

        updateTimeDisplay() {
          const current = this.formatTime(this.mainVideo.currentTime || 0)
          const duration = this.formatTime(this.mainVideo.duration || 0)
          this.timeDisplay.textContent = `${current} / ${duration}`
        }

        formatTime(seconds) {
          const mins = Math.floor(seconds / 60)
          const secs = Math.floor(seconds % 60)
          return `${mins.toString().padStart(2, '0')}:${secs
            .toString()
            .padStart(2, '0')}`
        }

        seekVideo(event) {
          if (!this.mainVideo.duration) return

          const rect = this.progressContainer.getBoundingClientRect()
          const clickX = event.clientX - rect.left
          const progress = clickX / rect.width
          const newTime = progress * this.mainVideo.duration

          this.mainVideo.currentTime = newTime
        }

        markTime(type) {
          if (!this.mainVideo.duration) {
            alert('请先加载视频')
            return
          }

          const currentTime = this.mainVideo.currentTime

          if (type === 'start') {
            this.currentSegment.start = currentTime
            this.markStartBtn.textContent = `开始: ${this.formatTime(
              currentTime
            )}`
          } else if (type === 'end') {
            this.currentSegment.end = currentTime
            this.markEndBtn.textContent = `结束: ${this.formatTime(
              currentTime
            )}`
          }

          // 如果开始和结束时间都已标记，自动添加片段
          if (
            this.currentSegment.start !== null &&
            this.currentSegment.end !== null
          ) {
            if (this.currentSegment.start >= this.currentSegment.end) {
              alert('结束时间必须大于开始时间')
              return
            }

            this.addSegmentFromMarked()
          }
        }

        addSegmentFromMarked() {
          const segment = {
            start: this.currentSegment.start,
            end: this.currentSegment.end,
            id: Date.now(),
          }

          this.segments.push(segment)
          this.updateSegmentsList()
          this.updateSegmentMarkers()

          // 重置标记
          this.currentSegment = { start: null, end: null }
          this.markStartBtn.textContent = '标记开始'
          this.markEndBtn.textContent = '标记结束'

          this.processBtn.disabled = false
        }

        addSegment() {
          const segment = {
            start: 0,
            end: 10,
            id: Date.now(),
          }

          this.segments.push(segment)
          this.addLog(
            `添加新片段: ${this.formatTime(segment.start)} - ${this.formatTime(
              segment.end
            )}`,
            'info'
          )
          this.updateSegmentsList()
          this.updateSegmentMarkers()
          this.processBtn.disabled = false
        }

        updateSegmentsList() {
          // 清空现有列表
          const existingItems = this.segmentsList.querySelectorAll(
            '.segment-item:not(#segmentTemplate)'
          )
          existingItems.forEach((item) => item.remove())

          // 添加片段项
          this.segments.forEach((segment) => {
            const item = this.segmentTemplate.cloneNode(true)
            item.style.display = 'flex'
            item.id = `segment-${segment.id}`

            // 将DOM元素关联到片段对象
            segment.element = item

            const startInput = item.querySelector('.start-time')
            const endInput = item.querySelector('.end-time')
            const durationText = item.querySelector('.duration-text')
            const removeBtn = item.querySelector('.remove-segment-btn')

            startInput.value = this.formatTime(segment.start)
            endInput.value = this.formatTime(segment.end)
            durationText.textContent = `${(segment.end - segment.start).toFixed(
              1
            )}秒`

            // 绑定时间输入事件
            startInput.addEventListener('change', () => {
              segment.start = this.parseTime(startInput.value)
              this.updateSegmentMarkers()
              durationText.textContent = `${(
                segment.end - segment.start
              ).toFixed(1)}秒`
            })

            endInput.addEventListener('change', () => {
              segment.end = this.parseTime(endInput.value)
              this.updateSegmentMarkers()
              durationText.textContent = `${(
                segment.end - segment.start
              ).toFixed(1)}秒`
            })

            // 绑定删除事件
            removeBtn.addEventListener('click', () => {
              this.removeSegment(segment.id)
            })

            this.segmentsList.appendChild(item)
          })
        }

        parseTime(timeStr) {
          const parts = timeStr.split(':')
          if (parts.length === 2) {
            return parseInt(parts[0]) * 60 + parseInt(parts[1])
          }
          return 0
        }

        removeSegment(segmentId) {
          const segmentToRemove = this.segments.find((s) => s.id === segmentId)
          if (segmentToRemove) {
            this.addLog(
              `移除片段: ${this.formatTime(
                segmentToRemove.start
              )} - ${this.formatTime(segmentToRemove.end)}`,
              'info'
            )
          }
          this.segments = this.segments.filter((s) => s.id !== segmentId)
          this.updateSegmentsList()
          this.updateSegmentMarkers()
          this.processBtn.disabled = this.segments.length === 0
          this.addLog(`当前片段数量: ${this.segments.length}`, 'info')
        }

        updateSegmentMarkers() {
          this.segmentMarkers.innerHTML = ''

          if (!this.mainVideo.duration) return

          this.segments.forEach((segment) => {
            // 创建移除片段的可视化标记
            const removeSegment = document.createElement('div')
            removeSegment.className = 'remove-segment'

            const startPercent = (segment.start / this.mainVideo.duration) * 100
            const endPercent = (segment.end / this.mainVideo.duration) * 100

            removeSegment.style.left = startPercent + '%'
            removeSegment.style.width = endPercent - startPercent + '%'

            this.segmentMarkers.appendChild(removeSegment)

            // 添加开始和结束标记
            const startMarker = document.createElement('div')
            startMarker.className = 'segment-marker'
            startMarker.style.left = startPercent + '%'
            this.segmentMarkers.appendChild(startMarker)

            const endMarker = document.createElement('div')
            endMarker.className = 'segment-marker'
            endMarker.style.left = endPercent + '%'
            this.segmentMarkers.appendChild(endMarker)
          })
        }

        async processVideo() {
          if (!this.isFFmpegLoaded) {
            this.addLog('FFmpeg 未加载完成，无法处理视频', 'error')
            alert('FFmpeg 还未加载完成，请稍后再试')
            return
          }

          if (!this.originalFile) {
            this.addLog('未选择视频文件', 'error')
            alert('请先上传视频文件')
            return
          }

          if (this.segments.length === 0) {
            this.addLog('未添加要移除的片段', 'error')
            alert('请至少添加一个要移除的片段')
            return
          }

          this.addLog('开始处理视频', 'info')
          this.addLog(
            `原始文件: ${this.originalFile.name} (${(
              this.originalFile.size /
              1024 /
              1024
            ).toFixed(2)} MB)`,
            'info'
          )
          this.addLog(`要移除的片段数量: ${this.segments.length}`, 'info')

          this.processBtn.disabled = true
          this.progressSection.classList.add('show')
          this.downloadSection.classList.remove('show')

          try {
            // 将文件写入 FFmpeg 文件系统
            const inputFileName = 'input.mp4'
            const outputFileName = 'output.mp4'

            this.updateProgress(10, '正在加载视频文件...')
            this.addLog('正在将视频文件写入 FFmpeg 文件系统...', 'info')

            const fileData = new Uint8Array(
              await this.originalFile.arrayBuffer()
            )
            this.ffmpeg.FS('writeFile', inputFileName, fileData)
            this.addLog(`视频文件已写入: ${inputFileName}`, 'success')

            this.updateProgress(20, '正在分析视频片段...')
            this.addLog('正在构建 FFmpeg 过滤器...', 'info')

            // 构建 FFmpeg 命令
            const filterComplex = this.buildFilterComplex()
            this.addLog(`FFmpeg 过滤器: ${filterComplex}`, 'info')

            this.updateProgress(30, '正在处理视频...')
            this.addLog('开始执行 FFmpeg 命令...', 'info')

            // 执行 FFmpeg 命令
            const ffmpegCommand = [
              '-i',
              inputFileName,
              '-filter_complex',
              filterComplex,
              '-map',
              '[out]',
              '-c:v',
              'libx264',
              '-c:a',
              'aac',
              outputFileName,
            ]
            this.addLog(
              `FFmpeg 命令: ffmpeg ${ffmpegCommand.join(' ')}`,
              'info'
            )

            await this.ffmpeg.run(...ffmpegCommand)
            this.addLog('FFmpeg 命令执行完成', 'success')

            this.updateProgress(90, '正在生成输出文件...')
            this.addLog('正在读取处理后的视频文件...', 'info')

            // 读取输出文件
            const outputData = this.ffmpeg.FS('readFile', outputFileName)
            this.addLog(
              `输出文件大小: ${(outputData.length / 1024 / 1024).toFixed(
                2
              )} MB`,
              'info'
            )

            // 创建下载链接
            const blob = new Blob([outputData.buffer], { type: 'video/mp4' })
            const url = URL.createObjectURL(blob)
            this.addLog('下载链接已生成', 'success')

            this.downloadBtn.onclick = () => {
              const a = document.createElement('a')
              a.href = url
              a.download = 'processed_video.mp4'
              a.click()
              this.addLog('用户下载了处理后的视频', 'info')
            }

            this.updateProgress(100, '处理完成!')
            this.addLog('视频处理完成！', 'success')

            setTimeout(() => {
              this.progressSection.classList.remove('show')
              this.downloadSection.classList.add('show')
            }, 1000)
          } catch (error) {
            this.addLog(`视频处理失败: ${error.message}`, 'error')
            console.error('视频处理失败:', error)
            alert('视频处理失败: ' + error.message)
            this.progressSection.classList.remove('show')
          } finally {
            this.processBtn.disabled = false
          }
        }

        buildFilterComplex() {
          // 对片段按开始时间排序
          const sortedSegments = [...this.segments].sort(
            (a, b) => a.start - b.start
          )

          let filterParts = []
          let currentTime = 0
          let inputIndex = 0

          sortedSegments.forEach((segment, index) => {
            // 添加片段前的部分
            if (currentTime < segment.start) {
              filterParts.push(
                `[0:v]trim=start=${currentTime}:end=${segment.start},setpts=PTS-STARTPTS[v${inputIndex}]`
              )
              filterParts.push(
                `[0:a]atrim=start=${currentTime}:end=${segment.start},asetpts=PTS-STARTPTS[a${inputIndex}]`
              )
              inputIndex++
            }

            currentTime = segment.end
          })

          // 添加最后一个片段后的部分
          if (currentTime < this.mainVideo.duration) {
            filterParts.push(
              `[0:v]trim=start=${currentTime},setpts=PTS-STARTPTS[v${inputIndex}]`
            )
            filterParts.push(
              `[0:a]atrim=start=${currentTime},asetpts=PTS-STARTPTS[a${inputIndex}]`
            )
            inputIndex++
          }

          // 构建连接命令
          let videoInputs = ''
          let audioInputs = ''
          for (let i = 0; i < inputIndex; i++) {
            videoInputs += `[v${i}]`
            audioInputs += `[a${i}]`
          }

          if (inputIndex > 1) {
            // 同时连接视频和音频
            let concatInputs = ''
            for (let i = 0; i < inputIndex; i++) {
              concatInputs += `[v${i}][a${i}]`
            }
            filterParts.push(
              `${concatInputs}concat=n=${inputIndex}:v=1:a=1[out]`
            )
            return filterParts.join(';')
          } else if (inputIndex === 1) {
            // 只有一个片段，直接输出
            filterParts.push('[v0][a0]concat=n=1:v=1:a=1[out]')
            return filterParts.join(';')
          } else {
            throw new Error('没有有效的视频片段')
          }
        }

        updateProgress(percent, text) {
          this.progressBarFill.style.width = percent + '%'
          this.progressText.textContent = text
        }

        // Tooltip 预览功能
        showProgressTooltip() {
          if (
            !this.mainVideo.src ||
            !this.mainVideo.duration ||
            isNaN(this.mainVideo.duration)
          )
            return

          this.progressTooltip.classList.add('show')
          this.tooltipVisible = true

          // 创建预览视频元素
          if (!this.previewVideo) {
            this.previewVideo = document.createElement('video')
            this.previewVideo.src = this.mainVideo.src
            this.previewVideo.muted = true
            this.previewVideo.style.width = '100%'
            this.previewVideo.style.height = '100%'
            this.previewVideo.style.objectFit = 'cover'

            const placeholder = this.progressPreview.querySelector(
              '.progress-preview-placeholder'
            )
            if (placeholder) {
              placeholder.style.display = 'none'
            }
            this.progressPreview.appendChild(this.previewVideo)
          }
        }

        updateProgressTooltip(event) {
          if (
            !this.tooltipVisible ||
            !this.mainVideo.src ||
            !this.mainVideo.duration ||
            isNaN(this.mainVideo.duration)
          )
            return

          const rect = this.progressContainer.getBoundingClientRect()
          const x = event.clientX - rect.left
          const percentage = Math.max(0, Math.min(1, x / rect.width))
          const time = percentage * this.mainVideo.duration

          // 更新提示位置
          const tooltipRect = this.progressTooltip.getBoundingClientRect()
          const tooltipWidth = tooltipRect.width

          // 计算提示框的左边距，确保宽度中心始终对应鼠标位置
          let leftPosition = x - tooltipWidth / 2

          // 更新时间显示
          this.progressTime.textContent = this.formatTime(time)

          // 更新预览视频时间
          if (
            this.previewVideo &&
            Math.abs(this.previewVideo.currentTime - time) > 0.5
          ) {
            this.previewVideo.currentTime = time
          }

          // 直接设置像素位置，确保宽度中心始终对应鼠标
          this.progressTooltip.style.left = leftPosition + 'px'
        }

        hideProgressTooltip() {
          this.progressTooltip.classList.remove('show')
          this.tooltipVisible = false

          // 清理预览视频
          if (this.previewVideo) {
            const placeholder = this.progressPreview.querySelector(
              '.progress-preview-placeholder'
            )
            if (placeholder) {
              placeholder.style.display = 'flex'
            }
            this.previewVideo.remove()
            this.previewVideo = null
          }
        }

        // 进度条交互处理函数
        handleProgressMouseDown(event) {
          if (!this.mainVideo.duration || event.button !== 0) return // 只响应左键

          event.preventDefault()
          event.stopPropagation()

          this.isLongPress = false
          this.isProgressInteracting = true // 标记开始进度条交互
          const rect = this.progressContainer.getBoundingClientRect()
          this.selectionStartX = event.clientX - rect.left
          const percentage = Math.max(
            0,
            Math.min(1, this.selectionStartX / rect.width)
          )
          this.selectionStartTime = percentage * this.mainVideo.duration

          // 设置长按定时器
          this.clickTimer = setTimeout(() => {
            this.isLongPress = true
            this.startRangeSelection()
          }, this.longPressThreshold)
        }

        handleProgressMouseMove(event) {
          // 更新tooltip
          if (this.tooltipVisible && !this.isProgressInteracting) {
            this.updateProgressTooltip(event)
          }

          // 更新范围选择
          if (this.isSelecting && this.isLongPress) {
            this.updateRangeSelection(event)
          }
        }

        handleProgressMouseUp(event) {
          // 只在真正的进度条交互时才处理
          if (!this.isProgressInteracting) return

          // 清除定时器
          if (this.clickTimer) {
            clearTimeout(this.clickTimer)
            this.clickTimer = null
          }

          if (this.isLongPress && this.isSelecting) {
            // 长按选择结束
            this.endRangeSelection(event)
          } else if (!this.isLongPress) {
            // 单击跳转
            this.seekVideo(event)
            // 单击后开始播放视频
            if (this.mainVideo.paused) {
              this.mainVideo.play()
            }
          }

          this.isLongPress = false
          this.isProgressInteracting = false // 重置交互标志
        }

        // 开始范围选择
        startRangeSelection() {
          this.isSelecting = true

          // 显示范围选择元素
          if (this.rangeSelectionElement) {
            this.rangeSelectionElement.style.display = 'block'
            this.rangeSelectionElement.style.left = this.selectionStartX + 'px'
            this.rangeSelectionElement.style.width = '0px'
          }
        }

        // 更新范围选择
        updateRangeSelection(event) {
          if (!this.isSelecting || !this.mainVideo.duration) return

          const rect = this.progressContainer.getBoundingClientRect()
          const currentX = event.clientX - rect.left
          const percentage = Math.max(0, Math.min(1, currentX / rect.width))
          const currentTime = percentage * this.mainVideo.duration

          // 计算选择范围
          const startX = Math.min(this.selectionStartX, currentX)
          const endX = Math.max(this.selectionStartX, currentX)
          const width = endX - startX

          // 更新选择范围显示
          if (this.rangeSelectionElement) {
            this.rangeSelectionElement.style.left = startX + 'px'
            this.rangeSelectionElement.style.width = width + 'px'
          }

          // 更新结束时间
          this.selectionEndTime = currentTime
        }

        // 结束范围选择
        endRangeSelection(event) {
          if (!this.isSelecting) return

          this.isSelecting = false

          // 如果选择了有效范围，自动标记起始和结束时间
          if (Math.abs(this.selectionEndTime - this.selectionStartTime) > 0.1) {
            // 至少0.1秒的差异
            const startTime = Math.min(
              this.selectionStartTime,
              this.selectionEndTime
            )
            const endTime = Math.max(
              this.selectionStartTime,
              this.selectionEndTime
            )

            // 添加新的移除片段
            this.addSegment()
            const segments = this.segments
            const newSegment = segments[segments.length - 1]

            if (newSegment) {
              // 设置起始和结束时间
              const startInput = newSegment.element.querySelector('.start-time')
              const endInput = newSegment.element.querySelector('.end-time')

              if (startInput && endInput) {
                startInput.value = this.formatTime(startTime)
                endInput.value = this.formatTime(endTime)

                // 更新片段数据
                newSegment.start = startTime
                newSegment.end = endTime

                this.updateSegmentMarkers()
                this.processBtn.disabled = false

                console.log(
                  `✅ 已选择移除范围: ${this.formatTime(
                    startTime
                  )} - ${this.formatTime(endTime)}`
                )
              }
            }
          }

          // 隐藏选择范围
          if (this.rangeSelectionElement) {
            this.rangeSelectionElement.style.display = 'none'
          }
        }

        // 日志系统方法
        addLog(message, type = 'info') {
          const timestamp = new Date().toLocaleTimeString()
          const logEntry = {
            timestamp,
            message,
            type,
            id: Date.now() + Math.random(),
          }

          this.logs.push(logEntry)
          this.displayLog(logEntry)

          // 自动滚动到底部
          setTimeout(() => {
            const logContainer = this.logContent.parentElement
            logContainer.scrollTop = logContainer.scrollHeight
          }, 10)
        }

        displayLog(logEntry) {
          const logElement = document.createElement('div')
          logElement.className = `log-entry ${logEntry.type}`
          logElement.innerHTML = `
            <span class="log-timestamp">[${logEntry.timestamp}]</span>
            <span class="log-message">${logEntry.message}</span>
          `
          this.logContent.appendChild(logElement)
        }

        clearLogs() {
          this.logs = []
          this.logContent.innerHTML = ''
          this.addLog('日志已清空', 'info')
        }

        openLogModal() {
          this.logModal.style.display = 'flex'
          document.body.style.overflow = 'hidden' // 防止背景滚动
        }

        closeLogModal() {
          this.logModal.style.display = 'none'
          document.body.style.overflow = 'auto' // 恢复背景滚动
        }

        downloadLogs() {
          if (this.logs.length === 0) {
            this.addLog('没有日志可下载', 'warning')
            return
          }

          const logText = this.logs
            .map(
              (log) =>
                `[${log.timestamp}] [${log.type.toUpperCase()}] ${log.message}`
            )
            .join('\n')

          const blob = new Blob([logText], { type: 'text/plain;charset=utf-8' })
          const url = URL.createObjectURL(blob)
          const a = document.createElement('a')
          a.href = url
          a.download = `video-segment-remover-logs-${new Date()
            .toISOString()
            .slice(0, 19)
            .replace(/:/g, '-')}.txt`
          document.body.appendChild(a)
          a.click()
          document.body.removeChild(a)
          URL.revokeObjectURL(url)

          this.addLog('日志文件已下载', 'success')
        }
      }

      // 初始化应用
      document.addEventListener('DOMContentLoaded', () => {
        new VideoSegmentRemover()
      })
    </script>
  </body>
</html>
